
package com.feib.soeasy.dao.hibernate;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.feib.soeasy.dao.RealAccountDao;
import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.RealAccount;
import com.feib.soeasy.pagination.PaginatedList;


/**
 * @title (#)RealAccountHibernateDao.java<br>
 * @description <br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2011/2/1 create by Jimmy Liu<br>
 */
@Repository("realAccountDao")
public class RealAccountHibernateDao extends BaseHibernateDao<RealAccount, Long> implements RealAccountDao {
    
    @SuppressWarnings("unchecked")
    public PaginatedList<RealAccount> queryPaginationByRealAccount(RealAccount realAccount, PaginatedList<RealAccount> paginationConfig)
    {
        PaginatedList<RealAccount> result = new PaginatedList<RealAccount>();
        result.setPageSize(paginationConfig.getPageSize());
        result.setPageNumber(paginationConfig.getPageNumber());
        result.setSortCriterion(paginationConfig.getSortCriterion());
        result.setSortDirection(paginationConfig.getSortDirection());
        
        result.setFullListSize(super.countByDetachedCriteria(createDetachedCriteriaByRealAccount(realAccount)));


        // 筆數大於0
        if (0 < result.getFullListSize())
        {
            DetachedCriteria criteria = createDetachedCriteriaByRealAccount(realAccount);

            //排序
            if (null != paginationConfig.getSortCriterion())
            {
                // 由小到大
                if (PaginatedList.SORT_DIRECTION_ASC == paginationConfig.getSortDirection())
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
                else // 由大到小
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
            }


            int maxResults = result.getPageSize(); //the maximum number of results
            int firstResult = result.getFirstIndexForCurrentPage();  //the first result to retrieve, numbered from 0
            result.setPaginatedList(this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults));
        }

        return result;
    }
    
    protected DetachedCriteria createDetachedCriteriaByRealAccount(RealAccount entity)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);

        Example example = Example.create(entity);
        example.enableLike(MatchMode.START);
        example.excludeZeroes();
        criteria.add(example);
        
        if (null != entity.getGroup())
        {
            DetachedCriteria detachedCriteria = criteria.createCriteria("group");

            // PK 有值，需加入為查詢條件
            if (null != entity.getGroup().getGroupPk())
            {
                detachedCriteria.add(Restrictions.idEq(entity.getGroup().getGroupPk()));
            }

            // Group 其他查詢條件
            Example e = Example.create(entity.getGroup());
            e.enableLike(MatchMode.START);
            e.excludeZeroes();
            detachedCriteria.add(e);
        }

        return criteria;
    }
    
    public void deleteByGroup(Group group)
    {
        StringBuffer hql = new StringBuffer();
        hql.append("delete RealAccount as r ");
        hql.append("where group = :group ");
        Query query = getSession().createQuery(hql.toString());
        query.setParameter("group", group);
        query.executeUpdate();
    }

    @SuppressWarnings("unchecked")
    public RealAccount queryByGroupVirtualAccount(RealAccount entity)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        criteria.add(Restrictions.eq("group", entity.getGroup()));
        
        DetachedCriteria detachedCriteria = criteria.createCriteria("group");
        detachedCriteria.add(Restrictions.idEq(entity.getGroup().getGroupPk()));
        
        List<RealAccount> rds = this.getHibernateTemplate().findByCriteria(criteria);
        if (0 != rds.size())
            return rds.get(0);
        else
            return null;

    }

    
    // added by julian for soez5008
    @SuppressWarnings("unchecked")
    public RealAccount queryByVirtualAccount(RealAccount entity)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        criteria.add(Restrictions.eq("virtualAccountNo", entity.getVirtualAccountNo()));
        
        List<RealAccount> rds = this.getHibernateTemplate().findByCriteria(criteria);
        if (0 != rds.size())
            return rds.get(0);
        else
            return null;

    }
    
    @SuppressWarnings("unchecked")
    public List queryByGroup(RealAccount entity)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        criteria.add(Restrictions.eq("group", entity.getGroup()));
        List<RealAccount> rds = this.getHibernateTemplate().findByCriteria(criteria);
        
        return rds;
        
    }
}
